from flask import Blueprint, jsonify, request
from app.models import UserModel, RoleModel
from json import dumps
from app.exts import db
from utils import scalars_to_list
from flask_jwt_extended import jwt_required
from app.forms.system.account import AccountAdd, AccountEdit
from secrets import token_hex
from werkzeug.security import generate_password_hash

account = Blueprint('account', __name__)


@account.put('/edit/password')
def account_edit_password():
    body = request.get_json()
    id = body.get('id')
    new_password = body.get('new_password')
    user_model = UserModel.query.get(id)
    # 随机生成密码盐
    salt = token_hex(5)
    # 加盐后的密码
    salt_password = generate_password_hash(new_password + salt)
    user_model.salt = salt
    user_model.password = salt_password
    try:
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        db.session.flush()
        return jsonify(code=500, message=str(e))

    return jsonify(code=200, message='修改成功')


@account.delete('/remove')
def account_remove():
    body = request.get_json()
    ids = body.get('ids') or []
    user_model = UserModel.query.filter(UserModel.id.in_(ids)).all()
    for user in user_model:
        db.session.delete(user)

    try:
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        db.session.flush()
        return jsonify(code=500, message=str(e))
    return jsonify(code=200, message='删除成功')


@account.put('/edit')
@jwt_required()
def account_edit():
    body = request.get_json()
    account_edit = AccountEdit(data=body)
    if not account_edit.validate():
        # 只获取第一个字典的错误信息
        error_first = next(iter(account_edit.errors.values()))[0]
        return jsonify(code=400, message=error_first)
    user_model = UserModel.query.get(body.get('id'))
    user_model.sort = body.get('sort')
    user_model.name = body.get('name')
    user_model.username = body.get('username')
    # 取出该用户所有分配的身份，预删除
    roles_all_ids = [u_m.id for u_m in user_model.roles]
    # 循环删除用户所有分配的身份
    for r_id in roles_all_ids:
        r_model = RoleModel.query.get(r_id)
        user_model.roles.remove(r_model)

    # 将客服端传入的权限 ids 关联于用户
    for r_id in body.get('roles_ids'):
        r_model = RoleModel.query.get(r_id)
        user_model.roles.append(r_model)
    try:
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        db.session.flush()
        return jsonify(code=500, message=str(e))
    return jsonify(code=200, message='修改成功')


@account.get('/list')
@jwt_required()
def account_list():
    page_number = request.args.get('page_number', default=1, type=int)
    page_size = request.args.get('page_size', default=10, type=int)
    role_id = request.args.get('role_id', type=int)
    name = request.args.get('name', type=str)
    username = request.args.get('username', type=str)
    user_query = UserModel.query
    # 根据身份 id 查询列表
    if role_id:
        user_query = user_query.join(UserModel.roles).filter(RoleModel.id == role_id)
    # 根据用户名称，模糊查询列表
    if name:
        user_query = user_query.filter(UserModel.name.like(f'%{name}%'))
    # 根据用户账号，模糊查询列表
    if username:
        user_query = user_query.filter(UserModel.username.like(f'%{username}%'))
    # 分页查询用户列表
    user_query = user_query.order_by(UserModel.sort).paginate(
        page=page_number,
        per_page=page_size,
        error_out=False
    )

    data = scalars_to_list(user_query.items)
    # 循环取出用户的身份权限
    for u in range(len(data)):
        # 推导式取出 权限名称、权限 id
        data[u]['roles_name'] = [r.name for r in user_query.items[u].roles]
        data[u]['roles_ids'] = [r.id for r in user_query.items[u].roles]

    return jsonify(code=200, message='获取成功', data=data, total=user_query.total)


@account.post('/add')
@jwt_required()
def account_add():
    body = request.get_json()
    account_add = AccountAdd(data=body)
    if not account_add.validate():
        # 只获取第一个字典的错误信息
        error_first = next(iter(account_add.errors.values()))[0]
        return jsonify(code=400, message=error_first)

    roles_ids = body.get('roles_ids')
    # 随机生成密码盐
    salt = token_hex(5)
    # 加盐后的密码，设置默认密码为：123456
    salt_password = generate_password_hash('123456' + salt)
    user_model = UserModel(
        name=body.get('name'),
        username=body.get('username'),
        sort=body.get('sort'),
        # 默认密码为 123456
        salt=salt,
        password=salt_password
    )
    for r_id in roles_ids:
        role_model = RoleModel.query.get(r_id)
        user_model.roles.append(role_model)

    try:
        db.session.add(user_model)
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        db.session.flush()
        return jsonify(code=500, message=str(e))
    return jsonify(code=200, message='添加成功')
